#include <stdio.h>

/* 【内存地址的占用大小】：
**  16位操作系统的内存地址占用大小是16位，即2字节
**  32位操作系统的内存地址占用大小是32位，即4字节
**  64位操作系统的内存地址占用大小是64位，即8字节
**  128位操作系统的内存地址占用大小是128位，即16字节
*/
int main(void){

    int urn[5] = {100,200, 300,400,500};
    int *ptr1,*ptr2,*ptr3;

    ptr1 = urn;
    ptr2 = &urn[2];
    /*【赋值】
    *说明：可以把地址赋值给指针
    *【解引用】
    *说明：*运算符给出指针指向地址上储存的值
    *【取址】
    *说明：和所有变量一样，指针变量也有自己的地址和值，对指针而言，&运算符给出指针本身的地址
    */
    printf("pointer value, dereferenced pointer, pointer address:\n");
    printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n",ptr1,*ptr1,&ptr1);

    /*【指针+整数】
    *说明：可以使用+运算符把指针与整数相加，整数会和指针所指向类型的大小（以字节为单位）相乘，然后把结果与初始值地址相加。
    *eg：ptr1+4 == &urn[4] / urn[4] == *（ptr1+4）
    */
    ptr3 = ptr1 + 4;
    printf("\nadding an int to a pointer:\n");
    printf("ptr1 + 4 = %p, urn[4] = %p, urn[4] = %d, *(ptr1 + 4) = %d\n",ptr1+4,&urn[4],urn[4],*(ptr1+4));
 
    /*【指针-整数】
    *注意：指针必须是第一个运算对象，整数只能是第二个运算对象。
    *说明：该整数将乘以指针指向类型的大小（以字节为单位），然后用初始地址减去乘积
    */
    printf("\nsubtracting an int from a pointer:\n");
    //假设此时ptr3为 0x7fff9bbbca70
    printf("ptr3 = %p, ptr3 - 2 = %p\n",ptr3,ptr3-2);//此时ptr3-2 = 0x7fff9bbbca68
 
    /*【递增指针】
    *说明：递增指向数组元素的指针可以让该指针移动至数组的下一个元素
    */
    ptr1++;//此时假设ptr为 0x7fff9bbbca60
    printf("\nvalues after ptr1++:\n");
    printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n",ptr1,*ptr1,&ptr1);//此时ptr1为 0x7fff9bbbca64
  
    /*【递减指针】
    *说明：递减指向数组元素的指针可以让该指针移动至数组的上一个元素
    */
    ptr2--;//ptr2 = &urn[2]; 假设此时ptr2为 0x7fff9bbbca68
    printf("\nvalues after --ptr2:\n");
    printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n",ptr2,*ptr2,&ptr2);//此时ptr2为 0x7fff9bbbca64

    --ptr1;//恢复为初始值   0x7fff9bbbca60
    ++ptr2;//恢复为初始值   0x7fff9bbbca68
    printf("\nPointers reset to original values:\n");
    printf("ptr1 = %p, ptr2 = %p\n",ptr1,ptr2);
 
    /*【指针求差】
    *说明：通常求差的两个指针分别指向同一个数组的不同元素，通过计算求出两元素之间的距离
    *eg:ptr2与ptr1这两个指针相隔2个int
    */
    printf("\nsubtracting one pointer from another:\n");
    printf("ptr2 = %p, ptr1 = %p, ptr2 - ptr1 = %td\n",ptr2,ptr1,ptr2-ptr1);


    return 0;
}